package vues;

import H4102.CartePanel;

import java.awt.Color;

import java.awt.Graphics;
import java.awt.Point;
import java.awt.geom.Point2D;

import java.util.ArrayList;
import sourceCode.Aeroport;
import sourceCode.Bagage;
import sourceCode.Chariot;
import sourceCode.Embranchement;
import sourceCode.Guichet;
import sourceCode.Rail;
import sourceCode.Tobogan;
import sourceCode.ZoneGarage;

public class VueAeroport extends Vue {

    private Aeroport aeroport;
    private int longueurPixelCartePanel;
    private int hauteurPixelCartePanel;
    private ArrayList<VueGuichet> vuesGuichets;
    private ArrayList<VueRail> vuesRails;
    private ArrayList<VueZoneGarage> vuesZonesGarages;
    private ArrayList<VueTobogan> vuesTobogans;
    private ArrayList<VueChariot> vuesChariots;
    private ArrayList<VueEmbranchement> vuesEmbranchements;
    private ArrayList<VueBagage> vuesBagages;
    private int longueurAeroportPixel;
    private int hauteurAeroportPixel;

    private boolean choixGuichet = false; //indique si on attend que l'utilisateur choisisse un guichet
    private boolean choixTobogan = false; //indique si on attend que l'utilisateur choisisse un guichet
    private boolean entreeSelectionnee;
    private boolean sortieSelectionnee;

    public VueAeroport(Aeroport a, CartePanel c) {
        super();
        this.longueurPixelCartePanel = c.getWidth();
        this.hauteurPixelCartePanel = c.getHeight();
        this.aeroport = a;
        //Point tailleAeroport = this.convertCoordonnesToPixels(new Point2D.Double(aeroport.getLongueur(),aeroport.getHauteur()));
        this.longueurAeroportPixel = c.getWidth();
        this.hauteurAeroportPixel = c.getHeight();
        this.vuesGuichets = new ArrayList<VueGuichet>();
        this.vuesRails = new ArrayList<VueRail>();
        this.vuesZonesGarages = new ArrayList<VueZoneGarage>();
        this.vuesTobogans = new ArrayList<VueTobogan>();
        this.vuesChariots = new ArrayList<VueChariot>();
        this.vuesEmbranchements = new ArrayList<VueEmbranchement>();
        this.vuesBagages = new ArrayList<VueBagage>();
        this.entreeSelectionnee = false;
        this.sortieSelectionnee = false;
    }

    public void initialiserVues() {
        for (Embranchement emb : this.aeroport.getListeEmbranchements()) {
            this.ajouterVueEmbranchement(emb);
        }

        for (Chariot chariot : this.aeroport.getListeChariots()) {
            this.ajouterVueChariot(chariot);
        }
        for (Guichet guichet :this. aeroport.getListeGuichets()) {
            this.ajouterVueGuichet(guichet);
        }

        for (Tobogan tobogan : this.aeroport.getListeTobogans()) {
            this.ajouterVueTobogan(tobogan);
        }

        for (Rail rail : this.aeroport.getListeRails()) {
            this.ajouterVueRail(rail);

        }
        for (Bagage bagage : this.aeroport.getListeBagages()) {
            this.ajouterVueBagage(bagage);
        }
        for (ZoneGarage garage : this.aeroport.getListeZonesGarages()) {
            this.ajouterVueZoneGarage(garage);
        }
    }

    public void rafraichirListeVues() {
        for (VueBagage vb : this.vuesBagages) {
            if (vb.getBagage().getConteneur() instanceof Tobogan) {
                this.vuesBagages.remove(vb);
                break;
            }
        }
    }

    public void ajouterVueChariot(Chariot chariot) {
        if (chariot != null) {
            VueChariot vueChariot = new VueChariot(this, chariot);
            this.ajouterVue(vueChariot);
        } else
            System.out.println("CartePanel.java : chariot est null");
    }

    public void ajouterVueGuichet(Guichet guichet) {
        if (guichet != null) {
            VueGuichet vueGuichet = new VueGuichet(this, guichet);
            this.ajouterVue(vueGuichet);
        } else
            System.out.println("CartePanel.java : guichet est null");
    }

    public void ajouterVueRail(Rail rail) {
        if (rail != null) {
            VueRail vueRail = new VueRail(this, rail);
            this.ajouterVue(vueRail);
        } else
            System.out.println("CartePanel.java : rail est null");
    }

    public void ajouterVueTobogan(Tobogan tobogan) {
        if (tobogan != null) {
            VueTobogan vueTobogan = new VueTobogan(this, tobogan);
            this.ajouterVue(vueTobogan);
        } else
            System.out.println("CartePanel.java : tobogan est null");
    }

    public void ajouterVueEmbranchement(Embranchement embranchement) {
        if (embranchement != null) {
            VueEmbranchement vueEmbranchement = new VueEmbranchement(this, embranchement);
            this.ajouterVue(vueEmbranchement);
        } else
            System.out.println("CartePanel.java : embranchement ou vueAeroport est null");
    }

    public void ajouterVueZoneGarage(ZoneGarage garage) {
        if (garage != null) {
            VueZoneGarage vueZoneGarage = new VueZoneGarage(this, garage);
            this.ajouterVue(vueZoneGarage);
        } else
            System.out.println("CartePanel.java : embranchement ou vueAeroport est null");
    }


    public void ajouterVueBagage(Bagage bagage) {
        if (bagage != null) {
            VueBagage vueBagage = new VueBagage(this, bagage);
            this.ajouterVue(vueBagage);
        } else
            System.out.println("CartePanel.java : embranchement ou vueAeroport est null");
    }


    public void ajouterVue(VueGuichet vue) {
        this.vuesGuichets.add(vue);
    }

    public void ajouterVue(VueTobogan vue) {
        this.vuesTobogans.add(vue);
    }

    public void ajouterVue(VueZoneGarage vue) {
        this.vuesZonesGarages.add(vue);
    }

    public void ajouterVue(VueRail vue) {
        this.vuesRails.add(vue);
    }

    public void ajouterVue(VueChariot vue) {
        this.vuesChariots.add(vue);
    }

    public void ajouterVue(VueEmbranchement vue) {
        this.vuesEmbranchements.add(vue);
    }

    public void ajouterVue(VueBagage vue) {
        this.vuesBagages.add(vue);
    }

    //Mode d'emploi: Fonction qui convertit en pixels et r?duit ? l'?chelle
    //une longueur en m?tre.
    //Entr?es:
    //double distMetreAConvertir: distance en m?tre ? convertir
    //double distPlanMaxMetre: distance r?f?rence en m?tre
    //int distFrameMaxPixels: distance en pixels ?quivalente ? la distance de r?f?rence en m?tre
    //Sortie:nombre de pixels correspondant.
    //Erreur:Null

    public int convertDistMetreToPixels(double distMetreAConvertir, double distPlanMaxMetre, int distFrameMaxPixels) {
        return (int)(distMetreAConvertir * distFrameMaxPixels / distPlanMaxMetre);
    }

    public int convertDistPixelsToMetre(double distMetreAConvertir, double distPlanMaxMetre, int distFrameMaxPixels) {
        return (int)(distMetreAConvertir * distPlanMaxMetre / distFrameMaxPixels);
    }

    //Mode d'emploi: Fonction qui convertit et r?duit ? l'?chelle les coordonn?es d'un point du m?tre aux pixels.
    //Entr?es:
    //double x: coordonn?e du point sur l'axe des abscisses
    //double y: coordonn?e du point sur l'axe des ordonn?es
    //double longPlanMaxMetre: longueur r?f?rence en m?tre
    //double hautPlanMaxMetre: hauteur r?f?rence en m?tre
    //int longFrameMaxPixels: longueur r?f?rence en pixels
    //int hautFrameMaxPixels: hauteur r?f?rence en pixels
    //Sortie:Point coordPixels: objet de type Point contenant les coordonn?es.
    //Erreur:Null

    public Point convertCoordonnesToPixels(Point2D.Double point) {
        double x = point.getX();
        double y = point.getY();
        double longPlanMaxMetre = this.aeroport.getLongueur();
        double hautPlanMaxMetre = this.aeroport.getHauteur();
        Point coordPixels =
            new Point(convertDistMetreToPixels(x, longPlanMaxMetre, this.longueurPixelCartePanel), convertDistMetreToPixels(y,
                                                                                                                            hautPlanMaxMetre,
                                                                                                                            this.hauteurPixelCartePanel));
        return coordPixels;
    }

    public Vue SelectElement(int x, int y) {
        Vue vue = null;
        for (VueZoneGarage vueIterator : this.vuesZonesGarages) {
            if (vueIterator.estCliquee(x, y) && vue == null) {
                vueIterator.setSelectionnee(true);
                vue = vueIterator;
            } else {
                vueIterator.setSelectionnee(false);
            }
        }
        for (VueChariot vueIterator : this.vuesChariots) {
            if (vueIterator.estCliquee(x, y) && vue == null) {
                vueIterator.setSelectionnee(true);
                vue = vueIterator;
            } else {
                vueIterator.setSelectionnee(false);
            }
        }
        for (VueRail vueIterator : this.vuesRails) {
            if (vueIterator.estCliquee(x, y) && vue == null) {
                vueIterator.setSelectionnee(true);
                vue = vueIterator;
            } else {
                vueIterator.setSelectionnee(false);
            }
        }
        for (VueGuichet vueIterator : this.vuesGuichets) {
            if (vueIterator.estCliquee(x, y) && vue == null) {
                vueIterator.setSelectionnee(true);
                vue = vueIterator;
            } else {
                vueIterator.setSelectionnee(false);
            }
        }
        for (VueTobogan vueIterator : this.vuesTobogans) {
            if (vueIterator.estCliquee(x, y) && vue == null) {
                vueIterator.setSelectionnee(true);
                vue = vueIterator;
            } else {
                vueIterator.setSelectionnee(false);
            }
        }
        for (VueZoneGarage vueIterator : this.vuesZonesGarages) {
            if (vueIterator.estCliquee(x, y) && vue == null) {
                vueIterator.setSelectionnee(true);
                vue = vueIterator;
            } else {
                vueIterator.setSelectionnee(false);
            }
        }
        return vue;
    }

    public VueGuichet chercheGuichet(int x, int y) {
        for (VueGuichet vueGuichet : vuesGuichets) {
            if (vueGuichet.estCliquee(x, y)) {
                if (vueGuichet.estPlein()) {
                    return null;
                } else {
                    return vueGuichet;
                }
            }
        }
        return null;
    }

    public VueTobogan chercheTobogan(int x, int y) {
        for (VueTobogan vueTobogan :this. vuesTobogans) {
            if (vueTobogan.estCliquee(x, y))
                return vueTobogan;
        }
        return null;
    }

    public void setEntreeSelectionne(boolean selectionnee) {
        this.entreeSelectionnee = selectionnee;
    }

    public void setSortieSelectionnee(boolean selectionnee) {
        this.sortieSelectionnee = selectionnee;
    }


    @Override
    public void dessiner(Graphics g) {
        g.setColor(new Color(0, 0, 0));
        g.drawRect(0, 0, this.longueurAeroportPixel - 1, this.hauteurAeroportPixel - 1);

        //dessin de tous les ?l?ments pr?sents dans l'a?roport
        for (VueRail vue : this.vuesRails) {
            vue.dessiner(g);
        }
        for (VueGuichet vue : this.vuesGuichets) {
            vue.dessiner(g);
        }
        for (VueTobogan vue : this.vuesTobogans) {
            vue.dessiner(g);
        }
        for (VueEmbranchement vue : this.vuesEmbranchements) {
            vue.dessiner(g);
        }
        for (VueChariot vue : this.vuesChariots) {
            vue.dessiner(g);
        }
        for (VueBagage vue : this.vuesBagages) {
            vue.dessiner(g);
        }
        for (VueZoneGarage vue : this.vuesZonesGarages) {
            vue.dessiner(g);
        }

    }

    @Override
    public String getType() {
        return "VueAeroport";
    }

    public Aeroport getAeroport() {
        return this.aeroport;
    }

    public int getLongueurPixelCartePanel() {
        return this.longueurPixelCartePanel;
    }

    public int getHauteurPixelCartePanel() {
        return this.hauteurPixelCartePanel;
    }

    public boolean isSortieSelectionnee() {
        return this.sortieSelectionnee;
    }

    public void ajouterBagage(VueGuichet vueGuichet, VueTobogan vueTobogan) {
        Bagage b = aeroport.ajouterBagage(vueGuichet.getGuichet(), vueTobogan.getTobogan());
        if (b != null) //Bagage a été créé
            this.vuesBagages.add(new VueBagage(this, b));
        else //Guichet plein
            ;
    }

    public void ajouterBagage(Bagage b) {
        if (b != null)
            this.vuesBagages.add(new VueBagage(this, b));
        else
            ;
    }

    public void setChoixGuichet(boolean choisirGuichet) {
        this.choixGuichet = choisirGuichet;
    }

    public boolean getChoixGuichet() {
        return this.choixGuichet;
    }

    public void setChoixTobogan(boolean choisirTobogan) {
        this.choixTobogan = choisirTobogan;
    }

    public boolean getChoixTobogan() {
        return this.choixTobogan;
    }

    public ArrayList<VueRail> getVuesRails() {
        return this.vuesRails;
    }

    public ArrayList<VueChariot> getVuesChariots() {
        return this.vuesChariots;
    }

    public ArrayList<VueGuichet> getVuesGuichets() {
        return this.vuesGuichets;
    }
}
